home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
RTVBE210.ZIP
/
_VESA2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-06
|
9KB
|
349 lines
;/************************************************************************
; *
; * File : _VESA.C
; *
; * Description : VBE-2.00 Interface
; *
; * Copyright (C) 1994,96 Realtech
; *
; ***********************************************************************/
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include "_standar.h"
#include "_vesa.h"
#include "_wdpmi.h"
#include "_dpmi.h"
VesaInfoBlock vesabuf;
VesaModeInfo modebuf;
VesaSystem VESA;
/*------------------------------------------------------------------------
*
* PROTOTYPE : void FAR48 *VBE_get_ptr_to_LFB(long physaddr)
*
* DESCRIPTION : Recupere l'adresse à remapper
*
*/
#define LIMIT4G 4096L*1024L-1L
ulong VESA_linAddr = 0;
ushort VESA_selAddr = 0;
void FAR48 *VBE_get_LFB(long physaddr,short *selector)
{
__dpmi_meminfo info;
if (VESA_linAddr)
{
info.address = VESA_linAddr;
__dpmi_free_physical_address_mapping(&info);
VESA_linAddr = 0;
}
if (VESA_selAddr)
{
__dpmi_free_ldt_descriptor(VESA_selAddr);
VESA_selAddr = 0;
}
VESA_selAddr = __dpmi_allocate_ldt_descriptors(1);
if (__dpmi_set_descriptor_access_rights(VESA_selAddr,0x8092)) error("PM right failed",8);
info.address = physaddr;
info.size = LIMIT4G;
if (!__dpmi_physical_address_mapping(&info)) // carry clear
{
VESA_linAddr = info.handle;
__dpmi_set_segment_base_address(VESA_selAddr,VESA_linAddr);
__dpmi_set_segment_limit(VESA_selAddr,LIMIT4G);
__dpmi_get_segment_base_address(VESA_selAddr,&VESA_linAddr);
#ifdef USE_VESAFAR
VESA.Video = NULL;
#else
VESA.Video = (uchar*)VESA_linAddr; //<<= Pointer to Video
#endif
VESA.Linear = 1;
*selector = (short)VESA_selAddr;
#ifdef __WATCOM__
return MK_FP(VESA_selAddr,0);
#else
return (void FAR48*)VESA_selAddr; //GNU C
#endif
}
error("Cannot remap address",info.address);
*selector = 0;
VESA.Linear = 0;
return NULL;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : int VBE_get_infos(int VESAmode)
*
* DESCRIPTION : Detecte si le mode est supporté par le BIOS
*
*/
int VBE_get_infos(int VESAmode)
{
__dpmi_regs regs;
regs.x.ax = 0x4F01;
regs.x.cx = VESAmode;
regs.x.di = 0;
memset(&modebuf,0,sizeof(VesaModeInfo));
PM_callES(0x10,®s, &modebuf, sizeof(VesaModeInfo));
return (regs.x.ax == 0x004F);
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : int Get_ModeByInfo(int width,int height,int bbp)
*
* DESCRIPTION : Recherche le numero de mode selon la taille de l'ecran desiré
*
*/
int VBE_get_mode_by_infos(int width,int height,int bbp)
{
int i;
for (i=0x100;i<=0x200;i++)
{
if (VBE_get_infos(i))
{
if ((modebuf.XResolution==width)
&&(modebuf.YResolution==height)
&&(modebuf.BitsPerPixel==bbp))
{
return i;
}
}
}
memset(&modebuf,0,sizeof(VesaModeInfo));
return 0;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : int VBE_get_OEM_infos(void)
*
* DESCRIPTION : Detecte si y a un BIOS VESA
* Essaye ensuite d'initialiser le mode en lineaire
*
*/
int VBE_get_OEM_infos(void)
{
__dpmi_regs regs;
memset(&vesabuf,0,sizeof(VesaInfoBlock));
strncpy(vesabuf.VESASignature,"VBE2",4);
/* Get SuperVGA information */
regs.x.ax = 0x4F00;
regs.x.di = 0;
PM_callES(0x10,®s, &vesabuf, sizeof(VesaInfoBlock));
if (regs.x.ax != 0x004F) return 0;
if (strncmp(vesabuf.VESASignature,"VESA",4) != 0)
{
memset(&vesabuf,0,sizeof(VesaInfoBlock));
VESA.Linear = 2;
return 0;
}
VESA.CardName = (char*)PHYSIC_ADRESS(vesabuf.OEMStringPtr);
return 1;
}
int VBE_set_mode(int mode)
{
__dpmi_regs regs;
regs.x.ax = 0x4F02;
regs.x.bx = mode;
__dpmi_int(0x10,®s);
if (regs.x.ax==0x004f)
{
// Some video card (like Matrox Millenium in 800x600)
// set a wrong scanline length . So we fix it !)
VBE_set_scanline_length(modebuf.XResolution);
return 1;
}
return 0;
}
#define vbeMemPK 4
#define vbeUseLFB 0x4000
#define vbeMdAvailable 0x0001
#define vbeMdColorMode 0x0008
#define vbeMdGraphMode 0x0010
#define vbeMdNonbanked 0x0040
#define vbeMdLinear 0x0080
int VBE_get_LFB_infos(void)
{
VESA.bankshift = 0;
VESA.Linear = 0;
VESA.LFB_actived = 0;
if ((modebuf.ModeAttributes & vbeMdAvailable)
&&(modebuf.ModeAttributes & vbeMdLinear))
{
VBE_get_LFB(modebuf.PhysBasePtr,&VESA.selector);
VESA.LFB_actived = VESA.Linear;
}
if (!VESA.Linear)
{
while ((64>>VESA.bankshift)!=modebuf.WinGranularity) VESA.bankshift++;
}
return 1;
}
int VBE_set_gfx_mode(int VESAmode)
{
if (VESAmode<0x100) error("Impossible",VESAmode);
return VBE_set_mode( VESA.LFB_actived ? VESAmode | vbeUseLFB : VESAmode);
}
int VBE_set_vesa_mode(int VESAmode)
{
if (!VBE_get_infos(VESAmode)) return 0;
VBE_get_LFB_infos();
return VBE_set_gfx_mode(VESAmode) ? vesabuf.VESAVersion : 0;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : bool set8BitPalette(void)
*
* DESCRIPTION : y a-t-il un DAC etendu 8Bit ?
*
*/
bool VBE_set8BitPalette(void)
{
__dpmi_regs regs;
regs.x.ax = 0x4F08; /* Set DAC service */
regs.x.bx = 0x0800; /* BH := 8, BL := 0 (set DAC width) */
__dpmi_int(0x10,®s);
if (regs.x.ax != 0x004F)
return false; /* Function failed, no wide dac */
if (regs.h.bh == 6)
return false;
regs.x.ax = 0x4F08;
regs.x.bx = 0x0001; /* Get DAC width (should now be 8) */
__dpmi_int(0x10,®s);
if (regs.x.ax != 0x004F)
return false;
if (regs.h.bh != 8)
return false;
return true;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : bool set6BitPalette(void)
*
* DESCRIPTION : y a-t-il un DAC etendu 6Bit ?
*
*/
bool VBE_set6BitPalette(void)
{
__dpmi_regs regs;
regs.x.ax = 0x4F08;
regs.x.bx = 0x0600;
__dpmi_int(0x10,®s); /* Restore to 6 bit DAC */
if (regs.x.ax != 0x004F)
return true;
if (regs.h.bh != 6)
return false;
return true;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : void CALLING_C setVESAPalette(ulong a, ulong b, void * pal)
*
* DESCRIPTION : Change 'b' couleurs à partir de 'a' avec la table 'pal'
*
*/
void CALLING_C VBE_set_palette(ulong a, ulong b, void * pal)
{
__dpmi_regs regs;
regs.x.ax = 0x1012;
regs.x.bx = a;
regs.x.cx = b;
regs.x.es = PMB.rseg;
regs.x.dx = PMB.roff;
PM_memcpyfn(PMB.sel,PMB.off, pal, (b-1) * 3);
//WaitSynchro();
__dpmi_int(0x10, ®s);
return;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : void getVESAPalette(int start, int num, uchar *palbuf)
*
* DESCRIPTION : recupere la palette en cours
*
*/
void VBE_get_palette(int start, int num, uchar *palbuf)
{
__dpmi_regs regs;
regs.x.ax = 0x1017;
regs.x.bx = start;
regs.x.cx = num;
regs.x.es = PMB.rseg;
regs.x.dx = PMB.roff;
__dpmi_int(0x10, ®s);
PM_memcpynf(palbuf, PMB.sel,PMB.off, num * 3);
return;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : BITBLT_xflip
*
* DESCRIPTION : Double Flipping en mode VESA 2.00
*
*/
void CALLING_C BITBLT_xflipVESA(void)
{
/*
__dpmi_regs regs;
ulong x;
VESA.offset = GXView.Page ? modebuf.YResolution : 0;
x = (ulong)VESA.offset * (ulong)modebuf.BytesPerLine;
GXView.video = GXView.ptr;
GXView.ptr = VESA.Video + x;
GXView.Page^=1;
regs.x.ax = 0x4F07;
regs.x.bx = 0x0000; //00h:set 01h:get 80h:during Vertical
regs.x.cx = 0;
regs.x.dx = GXView.Page ? modebuf.YResolution : 0;
__dpmi_int(0x10,®s);
WaitSynchro();
*/
return;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : void VESASetScanLineLength(long newcx)
*
* DESCRIPTION : Change le scanline (en bytes)
*
*/
void VBE_set_scanline_length(long newcx)
{
__dpmi_regs regs;
regs.x.ax = 0x4F06;
regs.x.bx = 0x0000; //Set Scanline
regs.x.cx = newcx;
regs.x.dx = 0x0000;
__dpmi_int(0x10,®s);
if (regs.x.ax!=2)
{
regs.x.ax = 0x4F06;
regs.x.bx = 0x0001; // Get Scanline
regs.x.dx = 0x0000;
__dpmi_int(0x10,®s);
if (regs.x.bx) modebuf.BytesPerLine = regs.x.bx;
}
return;
}
/*------------------------------------------------------------------------
*
* PROTOTYPE : void VESASetXY (long x,long y)
*
* DESCRIPTION : Change le start adress de la video
*
*/
void VBE_set_offset(long x,long y)
{
__dpmi_regs regs;
regs.x.ax = 0x4F07;
regs.x.bx = 0x0000;
regs.x.cx = x;
regs.x.dx = y;
__dpmi_int(0x10,®s);
return;
}